package com.bb.blog.activiti.impl;

import com.bb.blog.activiti.cmd.JumpCmd;
import com.bb.blog.activiti.cmd.TaskDelCmd;
import com.bb.blog.activiti.common.TaskDeleteReason;
import com.bb.blog.activiti.service.TaskActionService;
import com.bb.blog.activiti.service.TaskQueryService;
import com.bb.blog.web.exception.ServerException;
import lombok.RequiredArgsConstructor;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.engine.*;
import org.activiti.engine.history.DeleteReason;
import org.activiti.engine.impl.cmd.DeleteTaskCmd;
import org.activiti.engine.task.Task;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class TaskActionServiceImpl implements TaskActionService {
    private final HistoryService historyService;
    private final RuntimeService runtimeService;
    private final RepositoryService repositoryService;
    private final ManagementService managementService;
    private final TaskService taskService;
    private final TaskQueryService taskQueryService;

    @Override
    public void rollbackToPrevious(String taskId) {
        //根据要跳转的任务ID获取其任务
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Optional<Task> optionalTask = Optional.ofNullable(task);
        optionalTask.orElseThrow(() -> new ServerException(400, "任务不存在"));
        rollbackToPrevious(optionalTask.get());
    }

    @Override
    public void rollbackToPrevious(Task task) {
        Process mainProcess = repositoryService.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
        // 当前节点
        FlowNode flowNode = (FlowNode) mainProcess.getFlowElement(task.getTaskDefinitionKey());
        List<SequenceFlow> incomingFlows = flowNode.getIncomingFlows();
        if(incomingFlows.size() !=1){
            throw new ServerException(400, "找不到回退节点");
        }else{
            SequenceFlow sequenceFlow = incomingFlows.get(0);
           managementService.executeCommand(new JumpCmd(task.getId(), sequenceFlow.getSourceRef(),mainProcess, TaskDeleteReason.ROLL_BACK));
        }
    }

    @Override
    public void jump(String taskId, String nodeDefKey) {
        Task  task = taskQueryService.queryTaskById(taskId);
        Process mainProcess = repositoryService.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
        managementService.executeCommand(new JumpCmd(task.getId(), nodeDefKey, mainProcess, TaskDeleteReason.JUMP_NODE));
    }


}
